
import EventEmitter from "events";
import Modbus_RTU from './Modbus_RTU.js';
import moment from "moment";
class AK3300S extends EventEmitter {
    constructor(sn, link, interval = 122) {
        super();
        EventEmitter.call(this);
        //实时数据读取间隔 默认值60秒
        this.interval = interval;
        this.link = link;
        this.sn = sn;
        this.link.sn=sn;
        this.modbus = new Modbus_RTU(1, link);
        /**设备是否正忙 */
        this.isBusy = false;
        this.realData = [];
        /**设备参数 */

        this.readTimer = setInterval(() => this.poll(), this.interval * 1000);
        //最后一次通讯时间
        this.last_comm_time = moment();
    }

    setAddr(addr) {
        console.log(`设备${this.sn}设置地址为${addr}`);
        if(addr){
            this.modbus.setAddr(addr);
            console.log(`设备${this.sn}设置地址为${addr}成功`);
        }
    }


    reSetReadTimer() {
        clearInterval(this.readTimer);
        this.readTimer = setInterval(() => this.poll(), this.interval * 1000);
    }


    //设置读取实时数据的时间间隔
    setReadInterval(interval) {
        console.log(`设备${this.sn}设置读取实时数据的时间间隔为${interval}秒`);
        this.interval = interval;
        if (this.interval < 30) this.interval = 30; // 限制最小间隔不能小于30S
        clearInterval(this.readTimer);
        this.readTimer = setInterval(() => this.poll(), this.interval * 1000);
    }

    async poll() {

        await this.readRealData();
    }





    async readRealData() {
        if (this.isBusy) {
            console.log(`设备${this.address}读取实时数据忙，下一采集周期重试`);
            return;
        }
        this.isBusy = true;
        try {
            let data = await this.modbus.readFloat(0, 18);

            this.isBusy = false;
            if (data == null) return;
            if (data.length == 0) return;
            let db_data = {};

            db_data.quantity = data[0].value;
            db_data.balance = data[1].value;
            db_data.flow_rate = data[2].value;
            db_data.total_flow = data[3].value;
            db_data.ssrl = data[4].value;
            db_data.ljrl = data[5].value;
            db_data.pressure = data[6].value;
            db_data.temp = data[7].value;
            db_data.ylwll = data[8].value;
            db_data.wdwll = data[9].value;
            db_data.llwll = data[10].value;
            db_data.density = data[11].value;
            db_data.rhz = data[12].value;
            db_data.tjll = data[13].value;
            db_data.cyz = data[14].value;
            db_data.power = data[15].value;
            db_data.door = data[16].value;
            db_data.valve = data[17].value;
            db_data.read_time = moment().format('YYYY-MM-DD HH:mm:ss');
            console.log('realData', JSON.stringify(db_data));
            this.reSetReadTimer();
            this.emit('realData', this.sn, db_data);
            return db_data;
        } catch (error) {
            console.error("读取实时数据失败", error.message);
            return null;
        }
        finally {
            this.isBusy = false;

        }

    };


    /**校正时间
     * 
     */
    async ajustTime() {
        if (this.isBusy) {
            console.log(`设备${this.address}校正时间忙取消时间校正`);
            return { code: 0, err: "设备正忙请稍后重试" };
        }
        let now = moment();
        let year = now.year() - 2000;
        let month = now.month() + 1;
        let day = now.date();
        let hour = now.hour();
        let minute = now.minute();
        let second = now.second();
        let data = [year, month, day, hour, minute, second];
        let result = await this.modbus.writeUInt16(104, data);
        if (result == null || result == false) return { code: 0, err: "写入时间失败" };
        return { code: 1 };
    }

    async readParam() {
        if (this.isBusy) {
            console.log(`设备${this.address}读取参数忙取消参数读取`);
            return { code: 0, err: "设备正忙请稍后重试" };
        }
        let data = await this.modbus.readFloat(4, 43, 3);
        this.isBusy = false;
        if (data == null) return { code: 0, err: "读取参数失败" };
        let result = [];
        let index = 4;
        result.push({ name: '单价', value: data[0].value, addr: index }); index += 2;
        result.push({ name: '手动阀门控制', value: data[1].value, addr: index }); index += 2;
        result.push({ name: '阀门控制状态', value: data[2].value, addr: index }); index += 2;
        result.push({ name: '流量信号类型', value: data[3].value, addr: index }); index += 2;
        result.push({ name: '补偿方式', value: data[4].value, addr: index }); index += 2;
        result.push({ name: '流量系数', value: data[5].value, addr: index }); index += 2;
        result.push({ name: '固定密度', value: data[6].value, addr: index }); index += 2;
        result.push({ name: '流量输入上限', value: data[7].value, addr: index }); index += 2;
        result.push({ name: '补偿前单位', value: data[8].value, addr: index }); index += 2;
        result.push({ name: '补偿后单位', value: data[9].value, addr: index }); index += 2;
        result.push({ name: '流量零点修正', value: data[10].value, addr: index }); index += 2;
        result.push({ name: '流量满度修正', value: data[11].value, addr: index }); index += 2;
        result.push({ name: '小信号切除值', value: data[12].value, addr: index }); index += 2;
        result.push({ name: '流量数字滤波', value: data[13].value, addr: index }); index += 2;
        result.push({ name: '开平方功能', value: data[14].value, addr: index }); index += 2;
        result.push({ name: '工况温度', value: data[15].value, addr: index }); index += 2;
        result.push({ name: '工况压力', value: data[16].value, addr: index }); index += 2;
        result.push({ name: '小信号门限', value: data[17].value, addr: index }); index += 2;
        result.push({ name: '小流量协议值', value: data[18].value, addr: index }); index += 2;
        result.push({ name: '大流量门限', value: data[19].value, addr: index }); index += 2;
        result.push({ name: '大流量系数', value: data[20].value, addr: index }); index += 2;
        result.push({ name: '计费模式', value: data[21].value, addr: index }); index += 2;
        result.push({ name: '压力信号类型', value: data[22].value, addr: index }); index += 2;
        result.push({ name: '固定压力值', value: data[23].value, addr: index }); index += 2;
        result.push({ name: '压力输入上限', value: data[24].value, addr: index }); index += 2;
        result.push({ name: '压力输入下限', value: data[25].value, addr: index }); index += 2;
        result.push({ name: '压力零点修正', value: data[26].value, addr: index }); index += 2;
        result.push({ name: '压力满度修正', value: data[27].value, addr: index }); index += 2;
        result.push({ name: '压力数字过滤', value: data[28].value, addr: index }); index += 2;
        result.push({ name: '温度信号类型', value: data[29].value, addr: index }); index += 2;
        result.push({ name: '固定温度值', value: data[30].value, addr: index }); index += 2;
        result.push({ name: '温度输入上限', value: data[31].value, addr: index }); index += 2;
        result.push({ name: '温度输入下限', value: data[32].value, addr: index }); index += 2;
        result.push({ name: '温度零点修正', value: data[33].value, addr: index }); index += 2;
        result.push({ name: '温度满度修正', value: data[34].value, addr: index }); index += 2;
        result.push({ name: '温度数字过滤', value: data[35].value, addr: index }); index += 2;
        result.push({ name: '仪表类型', value: data[36].value, addr: index }); index += 2;
        result.push({ name: '累积流量清零初始值', value: data[37].value, addr: index }); index += 2;
        result.push({ name: '累积流量清零通知', value: data[38].value, addr: index }); index += 2;
        result.push({ name: '温度门限', value: data[39].value, addr: index }); index += 2;
        result.push({ name: '压力门限', value: data[40].value, addr: index }); index += 2;
        result.push({ name: '环境压力', value: data[41].value, addr: index }); index += 2;
        result.push({ name: '差压上限', value: data[42].value, addr: index }); index += 2;

        return { code: 1, data: result, err: "" };

    }

    async readBlance() {
        if (this.isBusy) {
            console.log(`设备${this.address}读取余额忙，下一采集周期重试`);
            return;
        }
        this.isBusy = true;
        try {
            let data = await this.modbus.readFloat(0, 2);
            this.isBusy = false;
            if (data == null) {
                console.log('读取余额失败');
                return { code: 0, err: "读取余额失败" };
            }
            if (data.length == 0) {
                return { code: 0, err: `读取余额失败${error.message}` }
            }
            let db_data = {};
            db_data.quantity = data[0].value;
            db_data.balance = data[1].value;
            data = await this.modbus.readFloat(4, 1, 3);
            this.isBusy = false;
            if (data == null) return;
            if (data.length == 0) return;
            db_data.price = data[0].value;
            return { code: 1, data: db_data };
        } catch (error) {
            console.error("读取余额失败", error.message);
            return { code: 0, err: `读取余额失败${error.message}` };

        }
        finally {
            this.isBusy = false;

        }
    }

    async writeParam(addr, value) {
        if (this.isBusy) {
            console.log(`设备${this.address}写入参数忙取消参数写入`);
            return { code: 0, data: [], err: "设备正忙请稍后重试" };
        }
        // addr=addr*2;
        try {
            let result = await this.modbus.writeFloat(addr, value);
            this.isBusy = false;
            if (result == null || result == false) return { code: 0, err: "写入参数失败" };
            return { code: 1 };
        } catch (error) {
            console.error("写入参数失败", error.message);
            return { code: 0, err: "写入参数失败" };
        }
        finally {
            this.isBusy = false;
        }

    }
    async recharge(value) {
        if (this.isBusy) {
            console.log(`设备${this.address}充值忙取消充值`);
            return { code: 0, data: [], err: "设备正忙请稍后重试" };
        }
        let data = await this.modbus.readFloat(0, 1);

        if (data == null || data.length == 0) {
            console.log('读取余额失败');
            return { code: 0, err: "读取余额失败" };
        }

        // value = value + data[0].value;
        let balance = data[0].value;
        console.log('充值量', value, '充值前余量', balance);
        let result = await this.modbus.writeFloat(0, [value]);
        if (result == null || result == false) return { code: 0, err: "充值失败" };
        return { code: 1, c_balance: data[0].value + value,balance };
    }

    async changePrice(price) {
        if (this.isBusy) {
            console.log(`设备${this.address}忙取消充值`);
            return { code: 0, data: [], err: "设备正忙请稍后重试" };
        }
        let result = await this.modbus.writeFloat(4, [price]);
        if (result == null || result == false) return { code: 0, err: "修改价格失败" };
        return { code: 1 };
    }

    destroy() {
        clearInterval(this.readTimer);
        this.link.close();
        this.modbus = null;
    }

}

export default AK3300S;